﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AudiPyme.DAL;

namespace AudiPyme.BLL
{
    //Clase que sirve para formatear las relaciones Tipo Activo - Vulnerabildiades que tiene una empresa
    public class InstanciaTipActVulnTabla
    {
        int idTipoActivo;
        int idVulnerabilidad;
        String tipoActivo;
        String vulnerabilidad;

        public int IdTipoActivo
        {
            get { return idTipoActivo; }
            set { idTipoActivo = value; }
        }

        public int IdVulnerabilidad
        {
            get { return idVulnerabilidad; }
            set { idVulnerabilidad = value; }
        }

        public String TipoActivo
        {
            get { return tipoActivo; }
            set { tipoActivo = value; }
        }

        public String Vulnerabilidad
        {
            get { return vulnerabilidad; }
            set { vulnerabilidad = value; }
        }

        public InstanciaTipActVulnTabla()
        {
            idTipoActivo = 0;
            idVulnerabilidad = 0;
            tipoActivo = "";
            vulnerabilidad = "";
        }

        public InstanciaTipActVulnTabla(int IdTipoActivo, int IdVulnerabilidad, String TipoActivo, String Vulnerabilidad)
        {
            idTipoActivo = IdTipoActivo;
            idVulnerabilidad = IdVulnerabilidad;
            tipoActivo = TipoActivo;
            vulnerabilidad = Vulnerabilidad;
        }

        //Recoge las relaciones tipo activo - vulnerabilidad que tiene actualmente seleccionadas la empresa
        public static List<InstanciaTipActVulnTabla> RecogeInstanciasEmpresa(int EmpresaUsuario)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<InstanciaTipActVulnTabla> LRelaciones = new List<InstanciaTipActVulnTabla>();
            //Recogemos las Relaciones Tipo Activo - Amenaza - Criterio de Riesgo actuales de la Empresa
            IQueryable<InstanciaTipActVulnTabla> relTipActVulnQuery = (from i in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                                                       join t in agenteBD.TiposActivosEstablecer on i.IdTipoActivo equals t.IdTipoActivo
                                                                       join v in agenteBD.VulnerabilidadesEstablecer on i.IdVulnerabilidad equals v.IdVulnerabilidad
                                                                       where i.IdEmpresa == EmpresaUsuario && i.Actual == true
                                                                       select new InstanciaTipActVulnTabla { IdTipoActivo = i.IdTipoActivo, TipoActivo = t.TipoActivo, IdVulnerabilidad = v.IdVulnerabilidad, Vulnerabilidad = v.Vulnerabilidad }).Distinct().OrderBy(t => t.IdTipoActivo).ThenBy(v => v.IdVulnerabilidad);
            if (relTipActVulnQuery.Count() != 0)
            {
                LRelaciones = relTipActVulnQuery.ToList();
            }
            return LRelaciones;
        }

        //Recoge las instancias que tiene actualmente seleccionadas la empresa con el Tipo de Activo que coincida con el patrón de búsqueda TextoBuscar
        public static List<InstanciaTipActVulnTabla> RecogeInstanciasEmpresaPorTipoActivo(int IdEmpresa, String TextoBuscar)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<InstanciaTipActVulnTabla> LRelaciones = new List<InstanciaTipActVulnTabla>();
            //Recogemos las Relaciones Tipo Activo - Vulnerabilidad actuales de la Empresa cuyos tipo de activos coincidan con el patrón de búsqueda TextoBuscar
            IQueryable<InstanciaTipActVulnTabla> relTipActAmenCritQuery = (from i in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                                                           join t in agenteBD.TiposActivosEstablecer on i.IdTipoActivo equals t.IdTipoActivo
                                                                           join v in agenteBD.VulnerabilidadesEstablecer on i.IdVulnerabilidad equals v.IdVulnerabilidad
                                                                           where i.IdEmpresa == IdEmpresa && i.Actual == true && t.TipoActivo.Contains(TextoBuscar)
                                                                           select new InstanciaTipActVulnTabla { IdTipoActivo = i.IdTipoActivo, TipoActivo = t.TipoActivo, IdVulnerabilidad = v.IdVulnerabilidad, Vulnerabilidad = v.Vulnerabilidad }).Distinct().OrderBy(t => t.IdTipoActivo).ThenBy(v => v.IdVulnerabilidad);
            if (relTipActAmenCritQuery.Count() != 0)
            {
                LRelaciones = relTipActAmenCritQuery.ToList();
            }
            return LRelaciones;
        }

        //Recoge las instancias que tiene actualmente seleccionadas la empresa cuyas Vulnerabilidades coincidan con el patrón de búsqueda TextoBuscar
        public static List<InstanciaTipActVulnTabla> RecogeInstanciasEmpresaPorVulnerabilidad(int IdEmpresa, String TextoBuscar)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<InstanciaTipActVulnTabla> LRelaciones = new List<InstanciaTipActVulnTabla>();
            //Recogemos las Relaciones Tipo Activo - Vulnerabilidad actuales de la Empresa cuyas vulnerabilidades coincidan con el patrón de búsqueda TextoBuscar
            IQueryable<InstanciaTipActVulnTabla> relTipActAmenCritQuery = (from i in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                                                           join t in agenteBD.TiposActivosEstablecer on i.IdTipoActivo equals t.IdTipoActivo
                                                                           join v in agenteBD.VulnerabilidadesEstablecer on i.IdVulnerabilidad equals v.IdVulnerabilidad
                                                                           where i.IdEmpresa == IdEmpresa && i.Actual == true && v.Vulnerabilidad.Contains(TextoBuscar)
                                                                           select new InstanciaTipActVulnTabla { IdTipoActivo = i.IdTipoActivo, TipoActivo = t.TipoActivo, IdVulnerabilidad = v.IdVulnerabilidad, Vulnerabilidad = v.Vulnerabilidad }).Distinct().OrderBy(t => t.IdTipoActivo).ThenBy(v => v.IdVulnerabilidad);
            if (relTipActAmenCritQuery.Count() != 0)
            {
                LRelaciones = relTipActAmenCritQuery.ToList();
            }
            return LRelaciones;
        }



        //Recoge las relaciones tipo activo - vulnerabilidad que no están actualmente seleccionadas por la empresa
        public static List<InstanciaTipActVulnTabla> RecogePosiblesInstanciasIncluir(int IdEmpresa)
        {
            List<InstanciaTipActVulnTabla> LRelaciones = new List<InstanciaTipActVulnTabla>();
            //Lista de Tipos de Activos que hay actualmente en la Empresa. Sirve para que no salgan relaciones
            //cuyos tipos de activo no estén presentes en los activos elegidos por una empresa. De esta forma
            //se filtran relaciones que en la situación actual de la empresa no son necesarias mostar y por tanto,
            //no tendrían importancia en el Análisis de Riesgo al no existir activos de la empresa que afecten
            List<int> LTiposActivosEnEmpresa = ActivosEmpresaFactory.ActivosEmpresaTipoActivo(IdEmpresa);
            ModeloContainer agenteBD = new ModeloContainer();
            //Relaciones Tipo Activo-Vulnerabilidad actuales de la empresa
            var relacionesEmp = from i in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                where i.IdEmpresa == IdEmpresa && i.Actual == true
                                select new { i.IdTipoActivo, i.IdVulnerabilidad };
            var relacionesTotal = from m in agenteBD.Matriz_TiposActivosVulnerabilidadesEstablecer
                                  select new { m.IdTipoActivo, m.IdVulnerabilidad };
            //Hacemos una disyunción de ambos conjuntos para recoger las relaciones disponibles a añadir
            var relacionesExc = relacionesTotal.Except(relacionesEmp);
            //Formateamos para Bindear al GridView con las relaciones actuales obtenidas
            IQueryable<InstanciaTipActVulnTabla> relacionesQuery = (from i in relacionesExc
                                                                    join m in agenteBD.Matriz_TiposActivosVulnerabilidadesEstablecer on
                                                                          new { i.IdTipoActivo, i.IdVulnerabilidad } equals
                                                                          new { m.IdTipoActivo, m.IdVulnerabilidad }
                                                                    join t in agenteBD.TiposActivosEstablecer on m.IdTipoActivo equals t.IdTipoActivo
                                                                    join v in agenteBD.VulnerabilidadesEstablecer on m.IdVulnerabilidad equals v.IdVulnerabilidad
                                                                    join av in agenteBD.Matriz_AmenazasVulnerabilidadesEstablecer on v.IdVulnerabilidad equals av.IdVulnerabilidad
                                                                    join a in agenteBD.AmenazasEstablecer on av.IdAmenaza equals a.IdAmenaza
                                                                    where (from ac in agenteBD.ActivosEmpresaEstablecer
                                                                           select ac.IdTipoActivo).Contains(t.IdTipoActivo) && m.Actual == true && LTiposActivosEnEmpresa.Contains(m.IdTipoActivo)
                                                                    select new InstanciaTipActVulnTabla { IdTipoActivo = t.IdTipoActivo, TipoActivo = t.TipoActivo, IdVulnerabilidad = v.IdVulnerabilidad, Vulnerabilidad = v.Vulnerabilidad }).Distinct();
            if (relacionesQuery.Count() != 0)
            {
                LRelaciones = relacionesQuery.ToList();
            }

            return LRelaciones;
        }

        //Recoge las instancias que tiene actualmente seleccionadas la empresa con el Tipo de Activo que coincida con el patrón de búsqueda TextoBuscar
        public static List<InstanciaTipActVulnTabla> RelacionesPorTipoActivo(int IdEmpresa, string TextoBuscar)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<InstanciaTipActVulnTabla> LRelacionesTabla = new List<InstanciaTipActVulnTabla>();
            //Lista de Tipos de Activos que hay actualmente en la Empresa. Sirve para que no salgan relaciones
            //cuyos tipos de activo no estén presentes en los activos elegidos por una empresa. De esta forma
            //se filtran relaciones que en la situación actual de la empresa no son necesarias mostar y por tanto,
            //no tendrían importancia en el Análisis de Riesgo al no existir activos de la empresa que afecten
            List<int> LTiposActivosEnEmpresa = ActivosEmpresaFactory.ActivosEmpresaTipoActivo(IdEmpresa);
            //Relaciones Tipo Activo-Vulnerabilidad actuales de la empresa
            var relacionesEmp = from i in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                where i.IdEmpresa == IdEmpresa && i.Actual == true
                                select new { i.IdTipoActivo, i.IdVulnerabilidad };
            //Relaciones Tipo Activo-Vulnerabilidad actuales de la Base de Conocimiento (Matriz) con el Filtro de Tipo Activo
            IQueryable<Matriz_TiposActivosVulnerabilidades> LRelaciones = from m in agenteBD.Matriz_TiposActivosVulnerabilidadesEstablecer
                                                                          join t in agenteBD.TiposActivosEstablecer on m.IdTipoActivo equals t.IdTipoActivo
                                                                          where t.TipoActivo.Contains(TextoBuscar) && m.Actual == true
                                                                          select m;
            var relacionesTotal = from LR in LRelaciones
                                  select new { LR.IdTipoActivo, LR.IdVulnerabilidad };
            var relacionesExc = relacionesTotal.Except(relacionesEmp);
            //Formateamos para Bindear al GridView con las relaciones actuales obtenidas
            IQueryable<InstanciaTipActVulnTabla> relacionesQuery = (from i in relacionesExc
                                                                    join m in agenteBD.Matriz_TiposActivosVulnerabilidadesEstablecer on
                                                                          new { i.IdTipoActivo, i.IdVulnerabilidad } equals
                                                                          new { m.IdTipoActivo, m.IdVulnerabilidad }
                                                                    join t in agenteBD.TiposActivosEstablecer on m.IdTipoActivo equals t.IdTipoActivo
                                                                    join v in agenteBD.VulnerabilidadesEstablecer on m.IdVulnerabilidad equals v.IdVulnerabilidad
                                                                    join av in agenteBD.Matriz_AmenazasVulnerabilidadesEstablecer on v.IdVulnerabilidad equals av.IdVulnerabilidad
                                                                    join a in agenteBD.AmenazasEstablecer on av.IdAmenaza equals a.IdAmenaza
                                                                    where (from ac in agenteBD.ActivosEmpresaEstablecer
                                                                           select ac.IdTipoActivo).Contains(t.IdTipoActivo) && m.Actual == true && LTiposActivosEnEmpresa.Contains(m.IdTipoActivo)
                                                                    select new InstanciaTipActVulnTabla { IdTipoActivo = t.IdTipoActivo, TipoActivo = t.TipoActivo, IdVulnerabilidad = v.IdVulnerabilidad, Vulnerabilidad = v.Vulnerabilidad }).Distinct();
            if (relacionesQuery.Count() != 0)
            {
                LRelacionesTabla = relacionesQuery.ToList();
            }
            return LRelacionesTabla;
        }

        //Recoge las instancias que tiene actualmente seleccionadas la empresa con la Vulnerabilidad que coincida con el patrón de búsqueda TextoBuscar
        public static List<InstanciaTipActVulnTabla> RelacionesPorVulnerabilidad(int IdEmpresa, string TextoBuscar)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<InstanciaTipActVulnTabla> LRelacionesTabla = new List<InstanciaTipActVulnTabla>();
            //Lista de Tipos de Activos que hay actualmente en la Empresa. Sirve para que no salgan relaciones
            //cuyos tipos de activo no estén presentes en los activos elegidos por una empresa. De esta forma
            //se filtran relaciones que en la situación actual de la empresa no son necesarias mostar y por tanto,
            //no tendrían importancia en el Análisis de Riesgo al no existir activos de la empresa que afecten
            List<int> LTiposActivosEnEmpresa = ActivosEmpresaFactory.ActivosEmpresaTipoActivo(IdEmpresa);
            //Relaciones Tipo Activo-Vulnerabilidad actuales de la empresa
            var relacionesEmp = from i in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                where i.IdEmpresa == IdEmpresa && i.Actual == true
                                select new { i.IdTipoActivo, i.IdVulnerabilidad };
            //Relaciones Tipo Activo-Vulneabilidad actuales de la Base de Conocimiento (Matriz) con el Filtro de Vulnerabilidad
            IQueryable<Matriz_TiposActivosVulnerabilidades> LRelaciones = from m in agenteBD.Matriz_TiposActivosVulnerabilidadesEstablecer
                                                                          join t in agenteBD.VulnerabilidadesEstablecer on m.IdVulnerabilidad equals t.IdVulnerabilidad
                                                                          where t.Vulnerabilidad.Contains(TextoBuscar) && m.Actual == true
                                                                          select m;
            var relacionesTotal = from LR in LRelaciones
                                  select new { LR.IdTipoActivo, LR.IdVulnerabilidad };
            var relacionesExc = relacionesTotal.Except(relacionesEmp);
            //Formateamos para Bindear al GridView con las relaciones actuales obtenidas
            IQueryable<InstanciaTipActVulnTabla> relacionesQuery = (from i in relacionesExc
                                                                    join m in agenteBD.Matriz_TiposActivosVulnerabilidadesEstablecer on
                                                                          new { i.IdTipoActivo, i.IdVulnerabilidad } equals
                                                                          new { m.IdTipoActivo, m.IdVulnerabilidad }
                                                                    join t in agenteBD.TiposActivosEstablecer on m.IdTipoActivo equals t.IdTipoActivo
                                                                    join v in agenteBD.VulnerabilidadesEstablecer on m.IdVulnerabilidad equals v.IdVulnerabilidad
                                                                    join av in agenteBD.Matriz_AmenazasVulnerabilidadesEstablecer on v.IdVulnerabilidad equals av.IdVulnerabilidad
                                                                    join a in agenteBD.AmenazasEstablecer on av.IdAmenaza equals a.IdAmenaza
                                                                    where (from ac in agenteBD.ActivosEmpresaEstablecer
                                                                           select ac.IdTipoActivo).Contains(t.IdTipoActivo) && m.Actual == true && LTiposActivosEnEmpresa.Contains(m.IdTipoActivo)
                                                                    select new InstanciaTipActVulnTabla { IdTipoActivo = t.IdTipoActivo, TipoActivo = t.TipoActivo, IdVulnerabilidad = v.IdVulnerabilidad, Vulnerabilidad = v.Vulnerabilidad }).Distinct();
            if (relacionesQuery.Count() != 0)
            {
                LRelacionesTabla = relacionesQuery.ToList();
            }
            return LRelacionesTabla;
        }
    }
}
